"""Holds the standard actions of the application"""

import webbrowser

from PyQt4 import QtGui, QtCore

from functools import partial

import reports
import displayWidget
import cleaners
from iTunes_importer import readSongs, podcastFilter

def addMenu(menuBar, mainWindow, profiles, tableWidget, centralWidget):
    """Adds in the standard actions to the menu bar"""
    #Note, here also, we assume that there are only songs. Must be generalized
    menu=menuBar.addMenu('&File')
    actn=menu.addAction(QtGui.QIcon('icons//file.png'), 'Open a File',
                        FileOpener(mainWindow, tableWidget))
    actn.setShortcut(QtGui.QKeySequence.Open)
    menu.addAction(QtGui.QIcon('icons//folder.png'), 'Open a Folder',
                   FolderOpener(mainWindow, tableWidget))
    menu.addAction('Import From iTunes',
                   iTunesImport(mainWindow, tableWidget))
    menu.addAction(QtGui.QIcon('icons/exit.png'), 'Exit', mainWindow.close,
                   'ESC')
    menu=menuBar.addMenu('&Functions')
    try:
        menu.addAction('Restructure Files',
                       cleaners.RestructureFiles(profiles['Songs']))
    except KeyError:
        pass
    menu.addAction('Report', FormReport(profiles, centralWidget))

class FileOpener(object):
    """Opens a file dialog and adds in the files"""
    def __init__(self, mainWindow, tableWidget):
        self.acceptor=tableWidget.fileAcceptor
        self.mainWindow=mainWindow
    def __call__(self):
        filt='Songs (%s)'%(' '.join('*.'+typ for typ in
                                   self.acceptor.fileTypes))
        dialog=QtGui.QFileDialog(self.mainWindow, 'Open File', '.',
                                 filt)
        if dialog.exec_():
            self.acceptor.accept(str(fil) for fil in dialog.selectedFiles())

class FolderOpener(object):
    """Opens a folder dialog and adds in the folder"""
    def __init__(self, mainWindow, tableWidget):
        self.acceptor=tableWidget.fileAcceptor
        self.mainWindow=mainWindow
    def __call__(self):
        dialog=QtGui.QFileDialog(self.mainWindow, 'Open Folder', '.')
        dialog.setFileMode(QtGui.QFileDialog.Directory)
        if dialog.exec_():
            self.acceptor.accept(str(dr) for dr in dialog.selectedFiles())

class iTunesImport(object):
    def __init__(self, mainWindow, tableWidget):
        self.tableWidget=tableWidget
        self.mainWindow=mainWindow
    def __call__(self):
        dialog=QtGui.QFileDialog(self.mainWindow, 'iTunes Import', 'C:\Users',
                                 '*.xml')
        if dialog.exec_():
            elements=podcastFilter(readSongs(dialog.selectedFiles()[0]))
            self.tableWidget.addElements(elements)
            
def addHelp(menuBar, mainWindow):
    """To add in the help bar"""
    helpMenu=menuBar.addMenu('&Help')
    aboutAction=QtGui.QAction('&About', mainWindow)
    aboutAction.setShortcut('F1')
    aboutAction.setStatusTip('About the Program')
    aboutAction.triggered.connect(partial(about, mainWindow))
    helpMenu.addAction(aboutAction)

def about(mainWindow):
    """To show the information about this program"""
    msg="""A program to get new, good music for its users, and to effectively manage all of the media it knows about.

Created by Nikhil Murthy under DERANGED (derangedproducts@gmail.com)

Eleanor is named after the song 'Eleanor Rigby' by The Beatles."""
    QtGui.QMessageBox.about(mainWindow, 'About Eleanor', msg)

class FormReport(object):
    """The class used for the action of creating a report"""
    def __init__(self, profiles, centralWidget):
        self.__profiles=profiles
        self.__centralWidget=centralWidget
    def __call__(self):
        """Creates an input box to choose the profile and atts to be used"""
        self.box=ReportInputBox(self.__profiles)
        self.box.accepted.connect(self.__createReport)
        self.box.exec_()
    @QtCore.pyqtSlot()
    def __createReport(self):
        xAtt, yAtt, profile, outputType=self.box.getValues()
        if outputType=='Widget':
            profile=reports.formReportProfile(xAtt, yAtt, profile.elements)
            trayDisplay=displayWidget.TrayDisplay(profile,
                                                  self.__centralWidget)
            self.__centralWidget.addWidget('Report', trayDisplay)
        elif outputType=='HTML':
            report=reports.getCompleteReport(xAtt,yAtt,profile.elements)
            with open('report.html', 'w') as fil:
                fil.write(reports.htmlify(report))
            webbrowser.open('report.html')
        elif outputType=='Graph':
            report=reports.getCompleteReport(xAtt, None, profile.elements)
            reports.graph(report)

#Use a strategy instead of the if
class ReportInputBox(QtGui.QDialog):
    """Takes in the input required for the report"""
    def __init__(self, profiles):
        QtGui.QDialog.__init__(self)
        self.__profileList=profiles.values()
        layout=QtGui.QGridLayout(self)
        self.profileChoice=QtGui.QComboBox(self)
        self.profileChoice.addItems(profiles.keys())
        layout.addWidget(self.profileChoice,0,0,1,2)
        row=self.__makeAxisCombos(layout, 1)
        self.setChoices(0)
        self.profileChoice.currentIndexChanged.connect(self.setChoices)
        row=self.__makeOutputChoice(layout, row)
        self.__makeButtons(layout, row)
        self.setLayout(layout)
    def __makeAxisCombos(self, layout, row):
        """Creates the combo boxes for the choice of axes"""
        layout.addWidget(QtGui.QLabel('X-axis:', self), row, 0)
        self.xAttChoice=QtGui.QComboBox(self)
        layout.addWidget(self.xAttChoice, row, 1)
        layout.addWidget(QtGui.QLabel('Y-axis:', self), row+1, 0)
        self.yAttChoice=QtGui.QComboBox(self)
        layout.addWidget(self.yAttChoice, row+1, 1)
        return row+2
    def __makeOutputChoice(self, layout, row):
        """Creates the output choice widget"""
        layout.addWidget(QtGui.QLabel('Output:', self), row, 0)
        self.outputChoice=QtGui.QComboBox(self)
        self.outputChoice.addItems(('Widget', 'HTML', 'Graph'))
        layout.addWidget(self.outputChoice, row, 1)
        return row+1
    def __makeButtons(self, layout, row):
        """Creates the buttons"""
        acceptButton=QtGui.QPushButton('Accept', self)
        acceptButton.clicked.connect(self.accept)
        layout.addWidget(acceptButton, row, 0)
        cancelButton=QtGui.QPushButton('Reject', self)
        cancelButton.clicked.connect(self.reject)
        layout.addWidget(cancelButton, row, 1)
    @QtCore.pyqtSlot(int)
    def setChoices(self, num):
        """Sets the choices of the attribute choices"""
        self.xAttChoice.clear()
        self.xAttChoice.addItems(self.__profileList[num].atts)
        self.yAttChoice.clear()
        self.yAttChoice.addItem('None')
        self.yAttChoice.addItems(self.__profileList[num].atts)
    def getValues(self):
        """Gives the values chosen by the user"""
        yAtt=str(self.yAttChoice.currentText())
        if yAtt=='None': yAtt=None
        return [str(self.xAttChoice.currentText()),
                yAtt,
                self.__profileList[self.profileChoice.currentIndex()],
                str(self.outputChoice.currentText())]
